#pragma once

#include "RefCounted.h"
#include <vector>
#include <memory>
#include <string>

namespace Lisp
{
    template <typename T>
    using Ref = std::shared_ptr<T>;
    template <typename T>
    using Scoped = std::unique_ptr<T>;

    class ValType;
    using ValPtr = RefCountedPtr<ValType>;

    class Env;
    using EnvPtr = RefCountedPtr<Env>;

    class ListType;
    using ListPtr = RefCountedPtr<ListType>;

    using ValVec = std::vector<ValPtr>;
} // namespace Lisp

extern Lisp::ValPtr EVAL(Lisp::ValPtr ast, Lisp::EnvPtr env);
extern Lisp::ValPtr APPLY(Lisp::ValPtr op, Lisp::ListPtr args);
extern Lisp::ValPtr Readline(const std::string &prompt);